﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using Nakio.Framework.Client;
using Nakio.SystemAdministration.Commands;
using Nakio.SystemAdministration.CustomClasses;

namespace Nakio.SystemAdministration.UserControls.FileExplorer
{
    /// <summary>
    /// Interaction logic for FileExplorer.xaml
    /// </summary>
    public partial class FileExplorer
    {
        public FileExplorerTypes FileExplorerType { get; set; }
        private const object _dummyNode = null;
        public MainClient Client { get; set; }

        public FileExplorer()
        {
            InitializeComponent();
            Loaded += FileExplorer_Loaded;
        }

        void FileExplorer_Loaded(object sender, RoutedEventArgs e)
        {
            SetExplorerTypeComboInit();
        }

        private void SetExplorerTypeComboInit()
        {
            FileExplorerType = FileExplorerTypes.LocalExplorer;
            ExplorerTypeCombo.SelectionChanged += ExplorerTypeCombo_SelectionChanged;
            ExplorerTypeCombo.SelectedItem = FileExplorerType;

        }

        private bool IsLocalFileExplorer()
        {
            var selectedValue = (FileExplorerTypes)ExplorerTypeCombo.SelectedValue;
            return selectedValue.Equals(FileExplorerTypes.LocalExplorer);
        }

        private void ExplorerTypeCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {            
            var logicalDrives = Directory.GetLogicalDrives();

            if (!IsLocalFileExplorer())
            {
                var getLogicalDrivesCommand = new GetLogicalDrivesCommand();
                logicalDrives = Client.ExecuteCommandOnServer<string[]>(getLogicalDrivesCommand);
            }
            FillTreeViewWithDrives(logicalDrives);

            
        }       

        private void FillTreeViewWithDrives(IEnumerable<string> logicalDrives)
        {   
            FoldersTree.Items.Clear();
            foreach (string drive in logicalDrives)
            {
                var item = new TreeViewItem { Header = drive, Tag = drive };
                item.Items.Add(_dummyNode);
                item.Expanded += folder_Expanded;
                item.Selected += item_Selected;

                // Apply the attached property so that 
                // the triggers know that this is root item.
                TreeViewItemProps.SetIsRootLevel(item, true);
                FoldersTree.Items.Add(item);
            }
        }

        private void item_Selected(object sender, RoutedEventArgs e)
        {
            e.Handled = true;
            var item = (TreeViewItem) sender;
            var command = new GetCustomFileInfosCommand((string) item.Tag);

            if (IsLocalFileExplorer())
            {
               FillFileListView(command.GetCustomFileInfos());
            }
            else
            {
                var list = Client.ExecuteCommandOnServer<List<CustomFileInfo>>(command);
                FillFileListView(list);
            }
        }

        private void FillFileListView(IEnumerable<CustomFileInfo> list)
        {
            FileListView.BeginInit();
            FileListView.ItemsSource = new List<CustomFileInfo>(list);
            FileListView.EndInit();

        }

        private void folder_Expanded(object sender, RoutedEventArgs e)
        {
            var directoryInfos = new Dictionary<string, DirectoryInfo>();
            var item = (TreeViewItem)sender;

            if (!IsLocalFileExplorer())
            {
                var getDirectoriesCommand = new GetDirectoriesCommand((string)item.Tag);
                directoryInfos = Client.ExecuteCommandOnServer<Dictionary<string, DirectoryInfo>>(getDirectoriesCommand);
            }
            else
            {
                var directories = Directory.GetDirectories((string)item.Tag);
                foreach (var directory in directories)
                {
                    var directoryInfo = new DirectoryInfo(directory);
                    directoryInfos.Add(directory, directoryInfo);
                }
            }
            FillTreeWithDirectories(item, directoryInfos);
            
        }

        private void FillTreeWithDirectories(ItemsControl rootItem, Dictionary<string,DirectoryInfo> directoryInfos)
        {
           if (rootItem.Items.Count == 1 && rootItem.Items[0] == _dummyNode)
            {
                rootItem.Items.Clear();
                foreach (string dir in directoryInfos.Keys)
                {
                    var subitem = new TreeViewItem { Header = directoryInfos[dir].Name, Tag = dir };
                    subitem.Items.Add(_dummyNode);
                    subitem.Expanded += folder_Expanded;
                    subitem.Selected += item_Selected;
                    rootItem.Items.Add(subitem);
                }                
            } 
        }
    }
}